/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.plotnikov.pricemaker.gui.utils;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/**
 *
 * @author alexey
 */
public class AutoCompleteComboBox extends
        JComboBox implements JComboBox.KeySelectionManager {

    private String searchFor;
    private long lap;
    private Vector<ComboBoxEditedListener> editListeners = new Vector<ComboBoxEditedListener>();

    private class CBDocument extends PlainDocument {

        @Override
        public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
            if (str == null) {
                return;
            }
            super.insertString(offset, str, a);
            if (!isPopupVisible() && str.length() != 0) {
                fireActionEvent();
            }
        }
    }

    public AutoCompleteComboBox(){
        super();
        setToolTipText("Нажмите Shift+Enter для добавления новой записи");
        lap = new java.util.Date().getTime();
        setKeySelectionManager(this);
        final JTextField tf;
        if (getEditor() != null) {
            tf = (JTextField) getEditor().getEditorComponent();
            if (tf != null) {
                tf.setDocument(new CBDocument());
                tf.addKeyListener(new java.awt.event.KeyAdapter() {
                    @Override
                    public void keyPressed(java.awt.event.KeyEvent evt) {
                        if (evt.isShiftDown() && evt.getKeyCode()==KeyEvent.VK_ENTER){
                           fireComboBoxEditedListener(tf.getText());
                        }
                    }
                });

                addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent evt) {
//                        if (evt.getActionCommand().toLowerCase().equals("comboboxchanged")){
                            JTextField tf = (JTextField) getEditor().getEditorComponent();
                            String text = tf.getText();
                            ComboBoxModel aModel = getModel();
                            String current;
                            for (int i = 0; i < aModel.getSize(); i++) {
                                current = aModel.getElementAt(i).toString();
                                if (current.toLowerCase().startsWith(text.toLowerCase())) {
                                    tf.setText(current);
                                    setSelectedIndex(i);
                                    tf.setSelectionStart(text.length());
                                    tf.setSelectionEnd(current.length());
//                                    System.out.println("tttt: "+i);
                                    break;
                                }
                            }
                            
//                        }else if (evt.getActionCommand().toLowerCase().equals("comboboxedited")){
//                            fireComboBoxEditedListener(tf.getText());
//                        }
                    }
                });
            }
        }
    }

    public boolean addComboBoxEditedListener(ComboBoxEditedListener l){
        return editListeners.add(l);
    }

    public boolean removeComboBoxEditedListener(ComboBoxEditedListener l){
        return editListeners.remove(l);
    }

    private void fireComboBoxEditedListener(String fireText){
        if (fireText==null)
            fireText = "";
        for (Iterator<ComboBoxEditedListener> it = editListeners.iterator(); it.hasNext();) {
            ComboBoxEditedListener comboBoxEditedListener = it.next();
            comboBoxEditedListener.editValue(fireText);
        }
    }

    public int selectionForKey(char aKey, ComboBoxModel aModel) {
        long now = new java.util.Date().getTime();
        if (searchFor != null && aKey == KeyEvent.VK_BACK_SPACE && searchFor.length() > 0) {
            searchFor = searchFor.substring(0, searchFor.length() - 1);
        } else {
            //	System.out.println(lap);
            // Kam nie hier vorbei.
            if (lap + 1000 < now) {
                searchFor = "" + aKey;
            } else {
                searchFor = searchFor + aKey;
            }
        }
        lap = now;
        String current;
        for (int i = 0; i < aModel.getSize(); i++) {
            current = aModel.getElementAt(i).toString().toLowerCase();
            if (current.toLowerCase().startsWith(searchFor.toLowerCase())) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void fireActionEvent() {
        super.fireActionEvent();
    }
}
